package com.xingchi.tornado.security.provider;

import com.xingchi.tornado.security.model.IUser;
import com.xingchi.tornado.security.model.LoginData;
import com.xingchi.tornado.security.model.UsernamePasswordAuthenticationToken;
import com.xingchi.tornado.security.service.UsernamePasswordLoginRepository;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.util.Assert;

/**
 * 用户名密码认证
 *
 * @author xiaoya
 * @date 2025/3/10 11:35
 */
@Slf4j
public class UsernamePasswordAuthenticationProvider extends AbstractAuthenticationProvider {

    private final UsernamePasswordLoginRepository usernamePasswordLoginRepository;
    private final PasswordEncoder passwordEncoder;

    public UsernamePasswordAuthenticationProvider(UsernamePasswordLoginRepository usernamePasswordLoginRepository,
                                                  PasswordEncoder passwordEncoder) {
        this.usernamePasswordLoginRepository = usernamePasswordLoginRepository;
        this.passwordEncoder = passwordEncoder;
    }

    @Override
    public LoginData<? extends IUser> authenticateHandler(Authentication authentication) throws AuthenticationException {
        Assert.isInstanceOf(UsernamePasswordAuthenticationToken.class, authentication, "UsernamePasswordAuthenticationProvider only supports UsernamePasswordAuthenticationToken");

        UsernamePasswordAuthenticationToken authenticationToken = (UsernamePasswordAuthenticationToken) authentication;
        paramsChecks(authenticationToken);

        IUser user = usernamePasswordLoginRepository.loadUserByUsername(authenticationToken.getUsername());
        if (user == null) {
            throw new UsernameNotFoundException("用户不存在");
        }

        // 比较密码
        if (!passwordEncoder.matches(authenticationToken.getPassword(), user.getPassword())) {
            throw new BadCredentialsException("密码不正确");
        }

        LoginData<IUser> loginData = LoginData.initLoginData();
        loginData.setUser(user);
        return loginData;
    }


    public void paramsChecks(UsernamePasswordAuthenticationToken authenticationToken) {
        String username = authenticationToken.getUsername();
        String password = authenticationToken.getPassword();
        if (StringUtils.isBlank(username) || StringUtils.isBlank(password)) {
            throw new IllegalArgumentException("用户名或密码不能为空");
        }
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);
    }
}
